home *** CD-ROM | disk | FTP | other *** search
/ MPEG Toolkit / MPEG Toolkit.iso / os2 / mpegenc / misc / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-01  |  6.8 KB  |  315 lines

  1. /*
  2.  * Copyright (c) 1993 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  *
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  *
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21.  
  22. #include "tk.h"
  23.  
  24. #include "all.h"
  25.  
  26. #include <sys/file.h>
  27. #include <sys/stat.h>
  28. #include <sys/param.h>
  29. #include <time.h>
  30. #include <string.h>
  31. #include <dirent.h>
  32. #include <strings.h>
  33.  
  34. #define MAX_FILES   1000
  35. #define MAX_NAME_LEN    256
  36. #define MAX_STRING_LEN    MAX_NAME_LEN
  37.  
  38. extern char currentPath[MAXPATHLEN];
  39.  
  40. char    globString[1024];
  41.  
  42. static DIR *dfd;
  43.  
  44. void    ResetPath(void);
  45. int ListDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
  46.           char **argv);
  47. int ChangeDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
  48.           char **argv);
  49. void    SortFiles(int numStrings, char strings[MAX_FILES][MAX_NAME_LEN],
  50.           boolean *dirList, int permute[]);
  51.  
  52. static void    UpdatePath(Tcl_Interp *interp, char *directory);
  53. static boolean    MatchesGlob(char *string, char *glob);
  54.  
  55.  
  56.  
  57. void    ResetPath()
  58. {
  59. #ifdef SYSV
  60.     if ( getcwd(currentPath) == 0 )
  61. #else
  62.     if ( getwd(currentPath) == 0 )
  63. #endif
  64.     {
  65.     fprintf(stderr, "Error getting pathname!!!\n");
  66.     exit(1);
  67.     }
  68.  
  69.     strcpy(¤tPath[strlen(currentPath)], "/");
  70.  
  71.     dfd = opendir(currentPath);
  72.     if ( dfd == NULL )
  73.     {
  74.     fprintf(stderr, "can't open '%s'\n", currentPath);
  75.     exit(1);
  76.     }
  77. }
  78.  
  79.  
  80. static void    UpdatePath(Tcl_Interp *interp, char *directory)
  81. {
  82.     int length;
  83.     char *charPtr;
  84.  
  85.     length = strlen(currentPath);
  86.  
  87.     if ( strcmp(directory, "./") == 0 )
  88.     return /* nothing */ ;
  89.     else if ( strcmp(directory, "../") == 0 )
  90.     {
  91.     /* delete backwards up to '/' */
  92.  
  93.     if ( length < 2 )
  94.     {
  95.         fprintf(stderr, "Error:  backing up from root directory!!!\n");
  96.         exit(1);
  97.     }
  98.  
  99.     charPtr = ¤tPath[length-2];
  100.     while ( (charPtr != currentPath) && (*charPtr != '/') )
  101.         charPtr--;
  102.     charPtr++;    /* leave the '/' */
  103.     *charPtr = '\0';
  104.     }
  105.     else
  106.     {
  107.     strcpy(¤tPath[length], directory);
  108.     }
  109. }
  110.  
  111.  
  112. int ChangeDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
  113.           char **argv)
  114. {
  115.     char *directory = argv[1];
  116.  
  117.     UpdatePath(interp, directory);
  118.  
  119.     dfd = opendir(currentPath);
  120.     if ( dfd == NULL )
  121.     {
  122.     fprintf(stderr, "can't open '%s'\n", currentPath);
  123.     return TCL_OK;    /* shouldn't, really */
  124.     }
  125.  
  126.     return TCL_OK;
  127. }
  128.  
  129.  
  130. int ListDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
  131.           char **argv)
  132. {
  133.     struct dirent *dp;
  134.     struct stat stbuf;
  135.     char command[256];
  136.     char fileName[MAX_FILES][MAX_NAME_LEN];
  137.     boolean dirList[MAX_FILES];
  138.     int permute[MAX_FILES];
  139.     int    fileCount = 0;
  140.     register int index;
  141.     char fullName[MAXPATHLEN];
  142.     char    *restPtr;
  143.     static boolean first = TRUE;
  144.  
  145.     if ( first )
  146.     {
  147.     sprintf(globString, "*.ppm");
  148.     first = FALSE;
  149.     }
  150.  
  151.     sprintf(command, "ShowCurrentDirectory %s", currentPath);
  152.     Tcl_Eval(interp, command, 0, (char **) NULL);
  153.  
  154.     if ( dfd == NULL )
  155.     {
  156.     fprintf(stderr, "TRIED TO LIST NULL DIRECTORY\n");
  157.  
  158.     return TCL_OK;
  159.     }
  160.  
  161. /* check if root directory */
  162.     if ( strlen(currentPath) != 1 )
  163.     {
  164.     sprintf(fileName[fileCount], "../");
  165.     dirList[fileCount] = TRUE;
  166.     fileCount++;
  167.     }
  168.  
  169.     strcpy(fullName, currentPath);
  170.     restPtr = &fullName[strlen(fullName)];
  171.  
  172.     while ( (dp = readdir(dfd)) != NULL )
  173.     {
  174.     strcpy(restPtr, dp->d_name);
  175.     stat(fullName, &stbuf);
  176.  
  177.     if ( dp->d_name[0] != '.' )
  178.     {
  179.         if ( S_ISDIR(stbuf.st_mode) )
  180.         {
  181.         sprintf(fileName[fileCount], "%s/", dp->d_name);
  182.         dirList[fileCount] = TRUE;
  183.         fileCount++;
  184.         }
  185.         else
  186.         {
  187.         if ( MatchesGlob(dp->d_name, globString) )
  188.         {
  189.             strcpy(fileName[fileCount], dp->d_name);
  190.             dirList[fileCount] = FALSE;
  191.             fileCount++;
  192.         }
  193.         }
  194.     }
  195.     }
  196.  
  197.     SortFiles(fileCount, fileName, dirList, permute);
  198.  
  199.     for ( index = 0; index < fileCount; index++ )
  200.     {
  201.     sprintf(command, "AddBrowseFile %s", fileName[permute[index]]);
  202.     Tcl_Eval(interp, command, 0, (char **) NULL);
  203.     }
  204.  
  205.     closedir(dfd);
  206.  
  207.     return TCL_OK;
  208. }
  209.  
  210.  
  211. void    SortFiles(int numStrings, char strings[MAX_FILES][MAX_NAME_LEN],
  212.           boolean *dirList, int permute[])
  213. {
  214.     register int i, j;
  215.     int temp;
  216.     int    numDirs;
  217.     int    ptr;
  218.  
  219.     for ( i = 0; i < numStrings; i++ )
  220.     permute[i] = i;
  221.  
  222.     /* put all directories at front */
  223.     numDirs = 0;
  224.     ptr = numStrings-1;
  225.     while ( numDirs != ptr )
  226.     {
  227.     /* go past dirs */
  228.     while ( (numDirs < ptr) && (dirList[permute[numDirs]]) )
  229.         numDirs++;
  230.  
  231.     /* go past non-dirs */
  232.     while ( (numDirs < ptr) && (! dirList[permute[ptr]]) )
  233.         ptr--;
  234.  
  235.     if ( numDirs != ptr )
  236.     {
  237.         temp = permute[numDirs];
  238.         permute[numDirs] = ptr;
  239.         permute[ptr] = temp;
  240.     }
  241.     }
  242.  
  243.     if ( dirList[permute[numDirs]] )
  244.     numDirs++;
  245.  
  246.     for ( i = 0; i < numDirs; i++ )
  247.     for ( j = i+1; j < numDirs; j++ )
  248.     {
  249.         if ( strcmp(&strings[permute[j]][0], &strings[permute[i]][0]) < 0 )
  250.         {
  251.         temp = permute[j];
  252.         permute[j] = permute[i];
  253.         permute[i] = temp;
  254.         }
  255.     }
  256.  
  257.     for ( i = numDirs; i < numStrings; i++ )
  258.     for ( j = i+1; j < numStrings; j++ )
  259.     {
  260.         if ( strcmp(&strings[permute[j]][0], &strings[permute[i]][0]) < 0 )
  261.         {
  262.         temp = permute[j];
  263.         permute[j] = permute[i];
  264.         permute[i] = temp;
  265.         }
  266.     }
  267. }
  268.  
  269.  
  270. int SetBrowseGlob (ClientData nulldata, Tcl_Interp *interp,
  271.            int argc, char **argv)
  272. {
  273.     if (argc == 2 )
  274.     {
  275.     strcpy(globString, argv[1]);
  276.  
  277.     return TCL_OK;
  278.     }
  279.  
  280.     Tcl_AppendResult (interp, 
  281.             "wrong args: should be \"", argv[0]," string\"", (char *) NULL);
  282.     return TCL_ERROR;
  283. }
  284.  
  285.  
  286. static boolean    MatchesGlob(char *string, char *glob)
  287. {
  288.     char    *stringRight, *globRight;
  289.  
  290.     while ( (*glob != '\0') && (*glob != '*') )        /* match left side */
  291.     {
  292.     if ( (*string == '\0') || (*string != *glob) )
  293.         return FALSE;
  294.     string++;
  295.     glob++;
  296.     }
  297.  
  298.     if ( *glob == '\0' )    /* no star */
  299.     return TRUE;
  300.  
  301.     /* now match right side */
  302.     stringRight = &string[strlen(string)-1];
  303.     globRight = &glob[strlen(glob)-1];
  304.  
  305.     while ( *globRight != '*' )
  306.     {
  307.     if ( (stringRight < string) || (*stringRight != *globRight) )
  308.         return FALSE;
  309.     globRight--;
  310.     stringRight--;
  311.     }
  312.  
  313.     return TRUE;
  314. }
  315.